#!/usr/local/bin/perl -w

use App::Options (
    options => [qw(dbdriver dbclass dbhost dbname dbuser dbpass)],
    option => {
        dbclass  => { default => "App::Repository::MySQL", },
        dbdriver => { default => "mysql", },
        dbhost   => { default => "localhost", },
        dbname   => { default => "test", },
        dbuser   => { default => "", },
        dbpass   => { default => "", },
        log_level => { default => 0, },
    },
);

use Test::More qw(no_plan);
use lib "../App-Context/lib";
use lib "../../App-Context/lib";
use lib "../App-Repository/lib";
use lib "../../App-Repository/lib";
use lib "lib";
use lib "../lib";

use App;
use App::Repository;
use strict;

my $t_dir = (-d "t") ? "t" : ".";

use App::WorkQueue::Repository;

if (! -f "$t_dir/app.conf") {
    ok(1, "No dbuser given. Tests assumed OK. (add dbname=abc, dbuser=xxx, and dbpass=yyy to app.conf in 't' directory)");
    exit(0);
}

my $context = App->context(
    conf_file => "",
    conf => {
        Repository => {
            default => {
                class => $App::options{dbclass},
                dbdriver => $App::options{dbdriver},
                dbhost => $App::options{dbhost},
                dbname => $App::options{dbname},
                dbuser => $App::options{dbuser},
                dbpass => $App::options{dbpass},
                #table => {
                #    test_person => {
                #        primary_key => ["person_id"],
                #    },
                #},
            },
        },
    },
    debug_sql => $App::options{debug_sql},
    log_level => $App::options{log_level},
);

{
    my $db = $context->repository();
    #cheating... I know its a DBI, but I have to set up the test somehow
    my $dbh     = $db->{dbh};
    eval { $dbh->do("drop table t_hotel_shop_request"); };
    my $ddl     = <<EOF;
create table t_hotel_shop_request (
    shop_request_id        integer       not null auto_increment primary key,
    org_id                 integer       not null,

    prop_id                integer       not null,
    shop_data_source       varchar(255)  not null,
    shop_currency_cd       varchar(3)    not null,
    shop_pos_cd            varchar(255)  not null,
    los                    integer       not null,
    guests                 integer       not null,
    begin_arv_dt           date          not null,
    end_arv_dt             date          not null,
    dow                    varchar(13)   null,
    comp_id                text          null,

    scheduled_dttm         datetime      null,
    start_dttm             datetime      null,
    complete_dttm          datetime      null,
    change_dttm            datetime      null,
    request_status         char(1)       null,
    client_userid          varchar(99)   null,
    client_system_cd       varchar(5)    null,
    server_system_cd       varchar(5)    null,
    work_units             integer       null,
    work_units_complete    integer       null,
    work_units_error       integer       not null default 0,
    work_units_blank       integer       not null default 0,
    work_units_skipped     integer       not null default 0,
    request_msg            varchar(99)   null,
    email_notify           varchar(255)  null,
    email_type             varchar(24)   null,
    shop_units             integer       null,
    profile                varchar(255)  null,

    display_option         varchar(99)   null,
    view_data_sources      varchar(255)  null,
    date_sense             varchar(5)    null,
    comp_prod_id           text          null,
    rm_type                varchar(12)   null,
    accom                  varchar(16)   null,
    prev_day_compare       varchar(10)   null,
    compare_options        varchar(24)   null,
    cell_drilldown         varchar(5)    null,
    highlight_ind          varchar(3)    null,
    rate_details           varchar(20)   null,
    shop_data_age          varchar(10)   null,

    shop_host              varchar(32)   null,
    shop_priority          integer       not null default 2,
    shop_fresh_mins        integer       not null default 1080,
    file_output_ind        char(1)       null,
    override_data_source   char(3)       default NULL,
    comp_strat_cd          varchar(16)   not null default 'none',
    mkt_keyword            varchar(255)  null, -- or "city_nm, state_cd, US" or "city_nm, country_cd"
    shop_level             integer       null, -- number of pages deep to go in a mkt shop

    actual_data_source     varchar(11)   null,
    report_units           integer       not null default 0,

    index hotel_shop_sreq_ie2  (shop_host, request_status, shop_data_source, actual_data_source,
                                shop_priority, shop_request_id, begin_arv_dt),
    index hotel_shop_sreq_ie3  (request_status, shop_data_source, actual_data_source)
) TYPE=InnoDB
EOF
    $dbh->do($ddl);
}

{
    &run("hotel_shop_request");
    &run("hotel_shop_request2", 1);
}

sub run {
    my ($qname, $rerun) = @_;
    my $db = $context->repository();
    my $table = "t_hotel_shop_request";

    my ($errmsg, %colidx);
    my $columns = [qw(
        shop_request_id
        org_id prop_id shop_data_source
        shop_currency_cd shop_pos_cd los guests
        begin_arv_dt end_arv_dt dow comp_id comp_prod_id
        scheduled_dttm start_dttm complete_dttm change_dttm
        request_status client_userid client_system_cd server_system_cd
        work_units work_units_complete
        request_msg email_notify email_type shop_units profile
        work_units_error work_units_blank shop_host shop_priority shop_fresh_mins
        actual_data_source file_output_ind work_units_skipped override_data_source
        display_option prev_day_compare mkt_keyword shop_level
    )];
    for (my $i = 0; $i <= $#$columns; $i++) {
        $colidx{$columns->[$i]} = $i;
    }
    my (%num_workers_ds, %num_workers_ads);
    my %state = (
        num_workers => 0,
        max_workers => 2,
    );
    my %max_workers_ds = (
        TRV => 1,
        WEB => 2,
        GDS => 2,
        _DEFAULT => 2,
    );
    my %max_workers_ads = (
        gds_vhh => 1,
        gds_vmc => 1,
        gds_vsi => 1,
        gds_vic => 1,
        gds_vhy => 1,
        vhh => 1,
        vmc => 1,
        vsi => 1,
        vic => 1,
        vhy => 1,
    );
    my (%total_queued_workers, %total_running_workers, %work_units_accepted, %work_units_running);

    my $q = $context->work_queue($qname,
        class             => "App::WorkQueue::Repository",
        #id_attrib         => "shop_request_id,comp_id,begin_arv_dt,shop_data_source,los",
        auto_id_attrib    => "shop_request_id",
        status_attrib     => "request_status",
        client_id_attrib   => "shop_host",
        client_id          => "$App::options{host}:$qname",
        STATUS_UNBUFFERED => "N",
        STATUS_UNACQUIRED => "N",
        STATUS_ACQUIRED   => "R",
        STATUS_RELEASED   => "S",
        BUFFER_SIZE       => 1,
        table             => $table,
        columns           => $columns,
        sort_spec         => "N-shop_priority,N+shop_request_id,begin_arv_dt,comp_id",
        max_workers           => \%max_workers_ads,
        total_queued_workers  => \%total_queued_workers,
        total_running_workers => \%total_running_workers,
        work_units_accepted   => \%work_units_accepted,
        work_units_running    => \%work_units_running,
    );
    isa_ok($q, "App::WorkQueue");
    isa_ok($q, "App::WorkQueue::Repository");

    eval {
        $q->set_constraint(\%num_workers_ds,  \%max_workers_ds,  "shop_data_source");
        ok(1, "set_constraint(shop_data_source)");
        $q->set_constraint(\%num_workers_ads, \%max_workers_ads, "actual_data_source");
        ok(1, "set_constraint(actual_data_source)");
        $q->set_global_constraint(\%state, \%state, "num_workers", "max_workers");
        ok(1, "set_global_constraint(...)");
    };
    ok(!$@, "No errors [$@]");

    eval {
        $q->push({ pi => 3.1416 });
    };
    $errmsg = $@;
    $errmsg =~ s/ at .*//s if ($errmsg);
    ok($errmsg, "Error on $qname->push(hash) [$errmsg]");

    if (!$rerun) {
        &test_status_counts($q, 0, 0, 0, 0);
        &test_resource_buffer_counts($q, "TRV:trv", 0, 0);
        &test_resource_buffer_counts($q, "EXP:exp", 0, 0);
        &test_resource_buffer_counts($q, "WEB:vhh", 0, 0);
    }
    else {
        &test_status_counts($q, 1, 0, 1, 0);
        &test_resource_buffer_counts($q, "TRV:trv", 0, 0);
        &test_resource_buffer_counts($q, "EXP:exp", 0, 0);
        &test_resource_buffer_counts($q, "WEB:vhh", 0, 0);
    }

    my ($shop_request_id, $request_status, $shop_host);

    eval {
        $q->push([ 0,1,128,"TRV","USD","US",1,1,"2006-04-01","2006-04-30","1,2,3,4,5,6,7",128,"1",
            "2006-01-04 12:00:00", "2006-01-04 12:00:00", "2006-01-04 12:00:00", "2006-01-04 12:00:00", 
            "W", "spadkins", "MV", "MV", 90, 0, undef, "sadkins\@therubicongroup.com", "ShopReport", 90, "default",
            0, 0, "x", 2, 1800, "trv", undef, 0, undef, "compare.detail.html", "None", undef, 2, ]);
    };
    if (!$rerun) {
        ok(!$@, "No error on $qname->push(array) [$@]");
        ($shop_request_id,$request_status,$shop_host)= $db->get($table,{shop_request_id=>1},["shop_request_id","request_status","shop_host"]);
        is($shop_request_id, 1, "push(1) made it to the table");
        is($request_status, "N", "push(1) is N");
        #is($shop_host, $App::options{host}, "push(1) is $App::options{host}");
        &test_status_counts($q, 1, 0, 0, 0);
        &test_resource_buffer_counts($q, "TRV:trv", 1, 1);
    }
    else {
        ok(!$@, "No error on $qname->push(array) [$@]");
        ($shop_request_id,$request_status,$shop_host)= $db->get($table,{shop_request_id=>8},["shop_request_id","request_status","shop_host"]);
        is($shop_request_id, 8, "push(8) made it to the table");
        is($request_status, "N", "push(8) is N");
        #is($shop_host, $App::options{host}, "push(8) is $App::options{host}");
        &test_status_counts($q, 2, 0, 1, 0);
        &test_resource_buffer_counts($q, "TRV:trv", 1, 1);
    }
exit(0) if ($rerun);

    $q->push([ 4,1,128,"EXP","USD","US",1,1,"2006-04-01","2006-04-30","1,2,3,4,5,6,7",128,"1",
        "2006-01-04 13:00:00", "2006-01-04 12:00:00", "2006-01-04 12:00:00", "2006-01-04 12:00:00", 
        "W", "spadkins", "MV", "MV", 90, 0, undef, "sadkins\@therubicongroup.com", "ShopReport", 90, "default",
        0, 0, "x", 2, 1800, "exp", undef, 0, undef, "compare.detail.html", "None", undef, 2, ]);
    ($shop_request_id,$request_status,$shop_host)= $db->get($table,{shop_request_id=>4},["shop_request_id","request_status","shop_host"]);
    is($shop_request_id, 4, "push(4) made it to the table");
    is($request_status, "N", "push(4) is N");
    #is($shop_host, $App::options{host}, "push(4) is $App::options{host}");
    &test_status_counts($q, 2, 0, 0, 0);
    &test_resource_buffer_counts($q, "EXP:exp", 1, 1);

    $q->push([ 2,1,128,"TRV","USD","US",1,1,"2006-04-01","2006-04-30","1,2,3,4,5,6,7",129,"1",
        "2006-01-04 12:00:00", "2006-01-04 12:00:00", "2006-01-04 12:00:00", "2006-01-04 12:00:00", 
        "W", "spadkins", "MV", "MV", 90, 0, undef, "sadkins\@therubicongroup.com", "ShopReport", 90, "default",
        0, 0, "x", 2, 1800, "trv", undef, 0, undef, "compare.detail.html", "None", undef, 2, ]);
    ($shop_request_id,$request_status,$shop_host)= $db->get($table,{shop_request_id=>2},["shop_request_id","request_status","shop_host"]);
    is($shop_request_id, 2, "push(2) made it to the table");
    is($request_status, "N", "push(2) is N");
    #is($shop_host, $App::options{host}, "push(2) is $App::options{host}");
    &test_status_counts($q, 3, 0, 0, 0);
    &test_resource_buffer_counts($q, "TRV:trv", 1, 2);

    $q->push([ 3,1,128,"EXP","USD","US",1,1,"2006-04-01","2006-04-30","1,2,3,4,5,6,7",129,"1",
        "2006-01-04 12:00:00", "2006-01-04 12:00:00", "2006-01-04 12:00:00", "2006-01-04 12:00:00", 
        "W", "spadkins", "MV", "MV", 90, 0, undef, "sadkins\@therubicongroup.com", "ShopReport", 90, "default",
        0, 0, "x", 2, 1800, "exp", undef, 0, undef, "compare.detail.html", "None", undef, 2, ]);
    ($shop_request_id,$request_status,$shop_host)= $db->get($table,{shop_request_id=>3},["shop_request_id","request_status","shop_host"]);
    is($shop_request_id, 3, "push(3) made it to the table");
    is($request_status, "N", "push(3) is N");
    #is($shop_host, $App::options{host}, "push(3) is $App::options{host}");
    ($shop_request_id,$request_status,$shop_host)= $db->get($table,{shop_request_id=>4},["shop_request_id","request_status","shop_host"]);
    is($request_status, "N", "push(4) is back to N");
    &test_status_counts($q, 4, 0, 0, 0);
    &test_resource_buffer_counts($q, "EXP:exp", 1, 2);

    ###############################################################################
    # Test release() for unacquired
    ###############################################################################
    my $entry = [ 6,1,128,"TRV","USD","US",1,1,"2006-04-01","2006-04-30","1,2,3,4,5,6,7",129,"1",
        "2006-01-04 12:00:00", "2006-01-04 12:00:00", "2006-01-04 12:00:00", "2006-01-04 12:00:00", 
        "W", "spadkins", "MV", "MV", 90, 0, undef, "sadkins\@therubicongroup.com", "ShopReport", 90, "default",
        0, 0, "x", 4, 1800, "trv", undef, 0, undef, "compare.detail.html", "None", undef, 2, ];
    $q->push($entry);
    ($shop_request_id,$request_status,$shop_host)= $db->get($table,{shop_request_id=>6},["shop_request_id","request_status","shop_host"]);
    is($shop_request_id, 6, "push(6) made it to the table");
    is($request_status, "N", "push(6) is N");
    #is($shop_host, $App::options{host}, "push(6) is $App::options{host}");
    &test_status_counts($q, 5, 0, 0, 0);
    &test_resource_buffer_counts($q, "TRV:trv", 1, 3);

    my $entry2 = [ 7,1,128,"TRV","USD","US",1,1,"2006-04-01","2006-04-30","1,2,3,4,5,6,7",129,"1",
        "2006-01-04 12:00:00", "2006-01-04 12:00:00", "2006-01-04 12:00:00", "2006-01-04 12:00:00", 
        "W", "spadkins", "MV", "MV", 90, 0, undef, "sadkins\@therubicongroup.com", "ShopReport", 90, "default",
        0, 0, "x", 2, 1800, "trv", undef, 0, undef, "compare.detail.html", "None", undef, 2, ];
    $q->push($entry2);
    ($shop_request_id,$request_status,$shop_host)= $db->get($table,{shop_request_id=>6},["shop_request_id","request_status","shop_host"]);
    is($shop_request_id, 6, "push(6) made it to the table");
    is($request_status, "N", "push(6) is N");
    #is($shop_host, $App::options{host}, "push(6) is $App::options{host}");
    &test_status_counts($q, 6, 0, 0, 0);
    &test_resource_buffer_counts($q, "TRV:trv", 1, 4);

    $q->release($entry);
    ($shop_request_id,$request_status,$shop_host)= $db->get($table,{shop_request_id=>6},["shop_request_id","request_status","shop_host"]);
    is($request_status, "S", "release(6) is S");
    &test_status_counts($q, 5, 0, 0, 1);
    &test_resource_buffer_counts($q, "TRV:trv", 1, 3);

    $q->release($entry2);
    ($shop_request_id,$request_status,$shop_host)= $db->get($table,{shop_request_id=>7},["shop_request_id","request_status","shop_host"]);
    is($request_status, "S", "release(7) is S");
    &test_status_counts($q, 4, 0, 0, 2);
    &test_resource_buffer_counts($q, "TRV:trv", 1, 2);

    ###############################################################################
    # End of Test fo release() for unacquired
    ###############################################################################

    # locate()
    my @entries = $q->locate({shop_request_id => 1});
    is($#entries, 0, "locate(): got 1 entry with shop_request_id = 1");
    is($entries[0][0], 1, "locate(): got THE entry with shop_request_id = 1");

    my (%counts);
    $q->count_entries_by_attrib("shop_data_source",\%counts);
    is($counts{TRV}, 2, "TRV count");
    is($counts{EXP}, 2, "EXP count");
    %counts = ();
    $q->count_entries_by_attrib("shop_data_source",\%counts,"work_units");
    is($counts{TRV}, 180, "TRV work_unit count");
    is($counts{EXP}, 180, "EXP work_unit count");

    my ($e1, $e2, $e3, $e4);

    $e1 = $q->acquire();
    is($e1->[0], 1,     "Entry 1: id=1");
    is($e1->[3], "TRV", "Entry 1: shop_data_source=TRV");
    is($num_workers_ds{TRV},  1, "Entry 1: num_workers_ds{TRV} = 1");
    #is($num_workers_ads{trv}, 1, "Entry 1: num_workers_ads{TRV} = undef");
    is($state{num_workers},   1, "Entry 1: state{num_workers} = 1");
    &test_status_counts($q, 3, 0, 1, 2);
    &test_resource_buffer_counts($q, "TRV:trv", 1, 1);

    $max_workers_ds{EXP} = 0;
    $e3 = $q->acquire();
    is($e3, undef, "No entries to acquire (EXP constraint)");
    delete $max_workers_ds{EXP};
    &test_status_counts($q, 3, 0, 1, 2);
    &test_resource_buffer_counts($q, "EXP:exp", 1, 2);

    $e2 = $q->acquire();
    is($e2->[0], 3,     "Entry 3: id=3");
    is($e2->[3], "EXP", "Entry 3: shop_data_source=EXP");
    is($num_workers_ds{EXP},  1,     "Entry 3: num_workers_ds{EXP} = 1");
    is($num_workers_ads{EXP}, undef, "Entry 3: num_workers_ads{EXP} = undef");
    is($state{num_workers},   2,     "Entry 3: state{num_workers} = 2");
    &test_status_counts($q, 2, 0, 2, 2);
    &test_resource_buffer_counts($q, "EXP:exp", 1, 1);

    $q->release($e1);
    is($num_workers_ds{TRV},  0,     "Release 1: num_workers_ds{TRV} = 0");
    is($e1->[$colidx{request_status}], "S", "Entry 1 released: request_status = S");
    is($state{num_workers},   1,     "Release 1: state{num_workers} = 1");
    &test_status_counts($q, 2, 0, 1, 3);
    &test_resource_buffer_counts($q, "TRV:trv", 1, 1);

    {
        my $work_units = $e1->[$colidx{work_units}];
        $q->update($e1,
            [ "work_units_complete",
              "work_units_blank",
              "work_units_error",
              "work_units_skipped",
              "change_dttm",
              "complete_dttm" ],
            [ $work_units,
              7,
              6,
              5,
              "2006-01-31 00:00:00",
              "2006-01-31 00:00:00" ]);
        my ($work_units_complete, $work_units_blank, $work_units_error, $work_units_skipped) =
            $db->get($q->{table}, $q->_array_to_key_params($e1),
            [ "work_units_complete",
              "work_units_blank",
              "work_units_error",
              "work_units_skipped", ]);
        is($work_units_complete, $work_units, "Update: work_units_complete=$work_units");
        is($work_units_blank,    7,           "Update: work_units_blank=7");
        is($work_units_error,    6,           "Update: work_units_error=6");
        is($work_units_skipped,  5,           "Update: work_units_skipped=5");
    }

    $e1 = $q->acquire();
    is($e1->[0], 2,     "Entry 2: id=2");
    is($e1->[3], "TRV", "Entry 2: shop_data_source=TRV");
    is($num_workers_ds{TRV},  1,     "Entry 2: num_workers_ds{TRV} = 1");
    is($num_workers_ads{TRV}, undef, "Entry 2: num_workers_ads{TRV} = undef");
    is($state{num_workers},   2,     "Entry 2: state{num_workers} = 2");
    &test_status_counts($q, 1, 0, 2, 3);
    &test_resource_buffer_counts($q, "TRV:trv", 0, 0);

    $e3 = $q->acquire();
    is($e3, undef, "No entries to acquire (global constraint)");
    &test_status_counts($q, 1, 0, 2, 3);
    &test_resource_buffer_counts($q, "TRV:trv", 0, 0);
    &test_resource_buffer_counts($q, "EXP:exp", 1, 1);

    my ($num);
    $num = $q->num_entries();
    is($num, 1, "1 entries left total [NW]");
    $num = $q->num_entries("R");
    is($num, 2, "2 entries left [R]");
    $num = $q->num_entries("N");
    is($num, 1, "1 entries left [N]");

    is($num_workers_ds{EXP},  1,     "Entry 3: num_workers_ds{EXP} = 1 (still)");
    $q->unacquire($e2);
    &test_status_counts($q, 2, 0, 1, 3);
    &test_resource_buffer_counts($q, "EXP:exp", 2, 2);

    is($num_workers_ds{EXP},  0,     "Entry 3 unacquired: num_workers_ds{EXP} = 0");
    is($e2->[$colidx{request_status}], "N", "Entry 3 unacquired: request_status = N");

    $q->push([ 5,1,128,"WEB","USD","US",1,1,"2006-04-01","2006-04-30","1,2,3,4,5,6,7",128,"1",
        "2006-01-04 12:00:00", "2006-01-04 12:00:00", "2006-01-04 12:00:00", "2006-01-04 12:00:00", 
        "W", "spadkins", "MV", "MV", 90, 0, undef, "sadkins\@therubicongroup.com", "ShopReport", 90, "default",
        0, 0, "pompeii", 4, 1800, "vhh", undef, 0, undef, "compare.detail.html", "None", undef, 2, ]);
    is($q->{data}[0][0], 5, "Entry 5 sorted to top: high priority");
    &test_status_counts($q, 3, 0, 1, 3);
    &test_resource_buffer_counts($q, "WEB:vhh", 1, 1);

    #my $rows = $db->get_rows($table, {}, $columns, {order_by => ["shop_request_id"]});
    #foreach my $row (@$rows) {
    #    print "    ROW:[", join("|",@$row), "]\n";
    #}

    $e4 = $q->acquire();
    is($e4->[0], 5,     "Entry 5: id=5");
    is($e4->[3], "WEB", "Entry 5: shop_data_source=WEB");
    is($num_workers_ds{WEB},  1,     "Entry 5: num_workers_ds{WEB} = 1");
    is($num_workers_ads{vhh}, 1,     "Entry 5: num_workers_ads{vhh} = 1");
    is($state{num_workers},   2,     "Entry 5: state{num_workers} = 2");
    &test_status_counts($q, 2, 0, 2, 3);
    &test_resource_buffer_counts($q, "WEB:vhh", 0, 0);

    $q->release($e4);
    is($num_workers_ds{WEB},  0,     "Entry 5: num_workers_ds{WEB} = 0");
    is($num_workers_ads{vhh}, 0,     "Entry 5: num_workers_ads{vhh} = 0");
    is($state{num_workers},   1,     "Entry 5: state{num_workers} = 1");
    &test_status_counts($q, 2, 0, 1, 4);
    &test_resource_buffer_counts($q, "WEB:vhh", 0, 0);

    $e4 = $q->acquire();
    &test_status_counts($q, 1, 0, 2, 4);
    &test_resource_buffer_counts($q, "TRV:trv", 0, 0);

    $q->release($e4);
    &test_status_counts($q, 1, 0, 1, 5);
    &test_resource_buffer_counts($q, "TRV:trv", 0, 0);
}

sub test_status_counts {
    my ($q, $N_count, $W_count, $R_count, $S_count) = @_;
    my ($count);
    if (defined $N_count) {
        $count = $q->num_entries("N");
        is($count, $N_count, "N count is $N_count");
    }
    if (defined $W_count) {
        $count = $q->num_entries("W");
        is($count, $W_count, "W count is $W_count");
    }
    if (defined $R_count) {
        $count = $q->num_entries("R");
        is($count, $R_count, "R count is $R_count");
    }
    if (defined $S_count) {
        $count = $q->num_entries("S");
        is($count, $S_count, "S count is $S_count");
    }
}

sub test_resource_buffer_counts {
    my ($q, $resource_key, $buffer, $total) = @_;
    my $resource_counts = $q->_resource_counts();
    is($resource_counts->{buffer}{$resource_key}||0, $buffer, "$resource_key buffer count is $buffer");
    is($resource_counts->{total}{$resource_key}||0, $total, "$resource_key total count is $total");
}

exit 0;

